#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.common.component.service;

import ${package}.common.bean.vo.CodeApiVo;
import ${package}.common.bean.vo.CodeTypeApiVo;
import ${package}.common.bean.vo.JsonResult;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.openfeign.FeignClientBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

import static ${package}.common.emum.CacheNameConst.CR_CODE;

/**
 * Description: CodeService 管理Code
 * 是否启用远程Code管理
 * @author wenxiaopeng
 * @date 2021/06/15 09:34
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2019. All Rights Reserved.
 * </pre>
 */
@Slf4j
@EnableCaching
@Valid
@Component
@ConditionalOnProperty("yk.code.enabled")
@Order
public class CodeService {

	private final CodeClient codeClient;

	public CodeService(ApplicationContext applicationContext) {
		FeignClientBuilder clientBuilder = new FeignClientBuilder(applicationContext);
		String codeServerName = applicationContext.getEnvironment().getProperty("yk.code.server", "${prefix}-setup");
		FeignClientBuilder.Builder<CodeClient> builder = clientBuilder.forType(CodeClient.class, codeServerName);
		this.codeClient = builder.build();
	}
	/**
	 * Description:
	 * <查询代码树>
	 * @param codeType  代码类型
	 * @param code      子代码
	 * @param lazy      是否懒加载，即是否仅加载子级而不递归加载
	 * @author wenxiaopeng
	 * @date 12:17 2021/06/17
	 * @return ${package}.common.bean.vo.JsonResult<${package}.common.bean.vo.CodeApiVo>
	 **/
	@Caching(cacheable = {
			@Cacheable(value = CR_CODE, condition = "${symbol_pound}lazy", key = "'TREE_' + ${symbol_pound}codeType + ${symbol_pound}code + '_LAZY'"),
			@Cacheable(value = CR_CODE, condition = "!${symbol_pound}lazy", key = "'TREE_' + ${symbol_pound}codeType + ${symbol_pound}code")
	})
	public List<CodeApiVo> getCodeTypeTree(@NotNull String codeType, String code, boolean lazy) {
		return JsonResult.getOrDefault(codeClient.getCodesTree(codeType, code, lazy), Lists.newArrayListWithCapacity(0));
	}

	/**
	 * Description:
	 * <查询代码列表>
	 * @param codeType  代码类型
	 * @param code      子代码
	 * @param lazy      是否懒加载 true时仅返回当前层级
	 * @author wenxiaopeng
	 * @date 12:16 2021/06/17
	 * @return ${package}.common.bean.vo.JsonResult<${package}.common.bean.vo.CodeApiVo>
	 **/
	@Caching(cacheable = {
			@Cacheable(value = CR_CODE, condition = "${symbol_pound}lazy", key = "'LIST_' + ${symbol_pound}codeType + ${symbol_pound}code + '_LAZY'"),
			@Cacheable(value = CR_CODE, condition = "!${symbol_pound}lazy", key = "'LIST_' + ${symbol_pound}codeType + ${symbol_pound}code")
	})
	public List<CodeApiVo> getCodeTypeList(@NotNull String codeType, String code, boolean lazy) {
		return JsonResult.getOrDefault(codeClient.getCodesList(codeType, code, lazy), Lists.newArrayListWithCapacity(0));
	}

	/**
	 * Description:
	 * <查询代码含义>
	 * @param code  代码值
	 * @author wenxiaopeng
	 * @date 09:42 2021/06/22
	 * @return java.lang.String
	 **/
	@ApiOperation("查询代码含义")
	@Cacheable(value = CR_CODE, key = "'MEANING_OF_' + ${symbol_pound}code")
	public String meaning(@NotNull String code) {
		return JsonResult.getOrDefault(codeClient.meaning(code), code);
	}

	/**
	 * Description:
	 * <获取上级代码详情>
	 * @param code  获取指定代码上级代码详情
	 * @author wenxiaopeng
	 * @date 09:48 2021/06/22
	 * @return ${package}.common.bean.vo.CodeApiVo
	 **/
	@Cacheable(value = CR_CODE, key = "'UPPER_OF_' + ${symbol_pound}code")
	public CodeApiVo upperCode(@NotNull String code) {
		JsonResult<CodeApiVo> codeApiVoJsonResult = codeClient.upperCode(code);
		return JsonResult.getOrDefault(codeApiVoJsonResult, null);
	}

	/**
	 * Description:
	 * <获取已有代码类型列表>
	 * @author wenxiaopeng
	 * @date 09:48 2021/06/22
	 * @return ${package}.common.bean.vo.CodeTypeApiVo
	 **/
	@Cacheable(value = CR_CODE, key = "'CODE_TYPE_LIST'")
	public List<CodeTypeApiVo> getCodeTypeList() {
		JsonResult<List<CodeTypeApiVo>> codeTypeList = codeClient.getCodeTypeList();
		return JsonResult.getOrDefault(codeTypeList, Lists.newArrayListWithCapacity(0));
	}

}

